package fitness;

import java.util.ArrayList;

import fitness.EloRecord.Result;

import optimizers.ganeat.jankenpon.*;

public class EloResult extends FitnessResult {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static double baseScore = 1000;
	public static double victoryAdjust = 400; 
	
	public ArrayList<EloRecord> results = new ArrayList<EloRecord>();
	
	public void addResult(EloRecord result){
		if(result.opponentElo + victoryAdjust < this.finalResult() && result.victory == Result.VICTORY){
			return;
		} else if ( result.opponentElo - victoryAdjust > this.finalResult() && result.victory == Result.DEFEAT){
			return;
		}
		this.results.add(result);
		
	}
	
	@Override
	public Double[] getDecomposition() {
		Double[] ret = new Double[results.size()];
		for(int i=0; i<results.size(); i++){
			ret[i] = results.get(i).opponentElo;
			if(results.get(i).victory == Result.VICTORY){
				ret[i] += EloResult.victoryAdjust;
			} else if (results.get(i).victory == Result.DEFEAT){
				ret[i] -= EloResult.victoryAdjust;
			}
		}
		
		return ret;
	}

	@Override
	public double finalResult() {
		if(results.isEmpty()){
			return EloResult.baseScore;
		}
		double score = 0;
		for(int i=0; i<results.size(); i++){
			score += results.get(i).opponentElo + results.get(i).recordModifier();
		}
		return Math.max(0, score/((double) results.size()));
	}
	
	@Override
	public String toString(){
		String ans = "fitness: "+this.finalResult()+"=";
		ArrayList<EloRecord> clo = (ArrayList<EloRecord>) results.clone();
		for(EloRecord d : clo){
			ans+=d.opponentElo+"("+(d.victory==Result.VICTORY?"V":d.victory==Result.DEFEAT?"L":"D")+") (";
			for(int alpha=0; alpha < d.iplayed.length; alpha++){
				ans+=d.iplayed[alpha]+":"+d.uplayed[alpha]+" ";
			}
			ans+=") +";
		}
		
		return ans;
	}

	@Override
	public Object clone(){
		EloResult res = new EloResult();
		res.results = (ArrayList<EloRecord>) this.results.clone();
		return res;
	}

	@Override
	public boolean goodSolution() {
		// TODO Auto-generated method stub
		return false;
	}
	
}
